/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package arbol_sintactico_abstracto;

import analizadorlexico.Token;
import java.io.IOException;
import java.util.List;
import tabla_de_simbolos.Clase;
import tabla_de_simbolos.Constructor;
import tabla_de_simbolos.ErrorSemantico;
import tabla_de_simbolos.ModificadorMetodo;
import tabla_de_simbolos.TablaDeSimbolos;
import tabla_de_simbolos.Tipo;
import generador_de_codigo.GeneradorDeCodigo;

/**
 *
 * @author Javi
 */
public class New extends Primario {
    private Token id;
    private List<Expresion> args;
    private List<Llamada> listaLlamadas;

    public New(Token id, List<Expresion> args, List<Llamada> listaLlamadas) {
        this.id = id;
        this.args = args;
        this.listaLlamadas = listaLlamadas;
    }   

    @Override
    public Tipo check(Clase clase, Constructor metodo, TablaDeSimbolos ts) throws ErrorSemantico, IOException{        
        Clase c = ts.getListaClases().get(id.getLexema());

      
        if(c == null)
            throw new ErrorSemantico("El constructor " + id.getLexema() + " no se corresponde con ninguna clase. Linea: "+id.getLinea());
        
        String etiqueta= c.getNombre()+"_Ctor";
        GeneradorDeCodigo.generar("RMEM 1 \n");
             
        GeneradorDeCodigo.generar("PUSH " + c.getOffsetAt() + "\n"); //capaz falta sumarle uno!
        GeneradorDeCodigo.generar("PUSH simple_malloc \n");
        GeneradorDeCodigo.generar("CALL \n");
        GeneradorDeCodigo.generar("DUP \n");
        GeneradorDeCodigo.generar("PUSH VT_" + c.getNombre() + "\n"); //pongo la etiqueta de la VT
        GeneradorDeCodigo.generar("STOREREF 0 \n"); //Enlazo la VT en el offset 0 del espacio reservado. La VT siempre tiene offset0
        //En el tope ahora queda el puntero al nuevo CIR ya que se duplico antes
        GeneradorDeCodigo.generar("DUP\n"); //this

        
        
        if(c.getConstructor().getParametros().size() != args.size())
                throw new ErrorSemantico("Cantidad de parametros incompatible. Linea: " + id.getLinea());
        
        for(int i = 0 ; i < args.size() ; i++){
            if(!args.get(i).check(clase, metodo,ts).conforma(c.getConstructor().getParametros().get(i).getTipo()))
                throw new ErrorSemantico("Paramentros incompatibles. Linea: " + id.getLinea());
             GeneradorDeCodigo.generar("SWAP \n");
        } 
        
        GeneradorDeCodigo.generar("PUSH "+ etiqueta +" \n");
        GeneradorDeCodigo.generar("CALL \n");
            
        Tipo aux = c;
        for(Llamada llamada : listaLlamadas){            
            aux = llamada.check(clase, metodo,aux,new ModificadorMetodo(new Token("dynamic", "dynamic", -1)),ts);            
        }
        return aux;
    }
}

